package demo.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

import cn.hutool.core.util.BooleanUtil;

/**
 * @program: mccken-collect
 * @description:
 * @author: mccken
 * @create: 2021-10-12 22:46
 **/
public class MyNIOClient {

	public static void main(String[] args) {
//		for (int i = 0; i < 10; i++) {
//			new Worker().start();
//		}

//		new Worker().start();

		SocketChannel channel = null;
		Selector selector = null;

		try {
			selector = Selector.open();
			channel = SocketChannel.open();

			channel.configureBlocking(false);
			boolean flag = channel.connect(new InetSocketAddress("localhost", 9001));
			if (BooleanUtil.isTrue(flag)) {
				System.out.println("connect done");
				channel.finishConnect();
			} else {
				System.out.println("connect fail ???");
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (channel!=null) {
				try {
					channel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (selector != null) {
				try {
					selector.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		
		
		
		
	}
	
	static class Worker extends Thread {

		@Override
		public void run() {
			SocketChannel channel = null;
			Selector selector = null;
			
			try {
				 selector = Selector.open();
				 channel = SocketChannel.open();
				 
				 channel.configureBlocking(false);
				boolean flag = channel.connect(new InetSocketAddress("localhost", 9000));
				if (BooleanUtil.isTrue(flag)) {
					System.out.println("connect done");
					channel.finishConnect();
				} else {
					System.out.println("connect fail ???");
					return;
				}

				channel.register(selector, SelectionKey.OP_CONNECT);
				 
				while (true) {
					selector.select();
					Set<SelectionKey> selectionKeys = selector.selectedKeys();
					Iterator<SelectionKey> iterator = selectionKeys.iterator();
					while (iterator.hasNext()) {
						SelectionKey key = iterator.next();
						iterator.remove();
						
						if (channel.isConnectionPending()) {

							if (key.isConnectable()) {
								channel = (SocketChannel) key.channel();
								ByteBuffer buffer = ByteBuffer.allocate(1024);
								buffer.put("你好".getBytes());
								buffer.flip();
								channel.write(buffer);
							}
							channel.register(selector, SelectionKey.OP_READ);
						}
						
						else if (key.isReadable()) {
							channel = (SocketChannel) key.channel();
							ByteBuffer buffer = ByteBuffer.allocate(1024);
							int len = channel.read(buffer);
							
							if (len>0) {
								System.out.println("[" + Thread.currentThread().getName() + "]收到响应: " + new String(buffer.array(), 0 , len));
								Thread.sleep(5000);
								channel.register(selector, SelectionKey.OP_WRITE);
							}
						}
						
						else if (key.isWritable()) {
							ByteBuffer buffer = ByteBuffer.allocate(1024);
							buffer.put("你好".getBytes());
							buffer.flip();
							
							channel = (SocketChannel) key.channel();
							channel.write(buffer);
							channel.register(selector, SelectionKey.OP_READ);
						}
					}
				}
				 
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (channel != null) {
					try {
						channel.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				
				if (selector != null) {
					try {
						selector.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}

		}
	}
	
}
